<!DOCTYPE html>
<html>
<head>
  <title>Ease visualizer | anime.js</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:title" content="anime.js">
  <meta property="og:url" content="http://animejs.com">
  <meta property="og:description" content="Javascript Animation Engine">
  <meta property="og:image" content="http://animejs.com/documentation/assets/img/icons/og.png">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:title" content="anime.js">
  <meta name="twitter:site" content="@juliangarnier">
  <meta name="twitter:description" content="Javascript Animation Engine">
  <meta name="twitter:image" content="http://animejs.com/documentation/assets/img/icons/twitter.png">
  <link rel="apple-touch-icon-precomposed" href="../assets/img/icons/apple-touch-icon.png">
  <link rel="icon" type="image/png" href="../assets/img/icons/favicon.png">
  <link href="../css/anime.css" rel="stylesheet">
  <script src="../js/anime.min.js"></script>
  <style>
    .easings {
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-direction: column;
      position: absolute;
      width: 100%;
      height: 100%;
    }
    .output {
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      width: 100%;
      height: 400px;
    }
    .options {
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
      width: 100%;
      min-height: 300px;
      border-top: 1px solid #09090B;
    }
    .grid {
      border-top: 1px solid rgba(255,255,255,0.2);
      border-right: 1px solid rgba(255,255,255,0.2);
      background: linear-gradient(0deg, rgba(255,255,255,0.2) 1px, rgba(0,0,0,0) 1px),
                  linear-gradient(90deg, rgba(255,255,255,0.2) 1px, rgba(0,0,0,0) 1px),
                  linear-gradient(0deg, rgba(255,255,255,0.1) 1px, rgba(0,0,0,0) 1px),
                  linear-gradient(90deg, rgba(255,255,255,0.1) 1px, rgba(0,0,0,0) 1px);
      background-position: 0px -1px;
      background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
    }
    .visualizer-wrapper {
      position: relative;
      width: 200px;
      height: 200px;
    }
    .visualizer {
      position: relative;
      width: 100px;
      height: 100px;
      transform: scale(2);
      transform-origin: 0 0;
    }
    .value {
      width: 20px;
      height: 200px;
      margin-left: 20px;
    }
    @media screen and (min-width: 980px) {
      .easings {
        flex-direction: row;
      }
      .output {
        width: 50%;
        height: 100%;
      }
      .options {
        width: 50%;
        height: 100%;
      }
      .visualizer-wrapper {
        width: 400px;
        height: 400px;
      }
      .visualizer {
        transform: scale(4);
      }
      .value {
        width: 40px;
        height: 400px;
        margin-left: 40px;
      }
    }
    .axis {
      opacity: 0;
      position: absolute;
      background: #5A87FF;
    }
    .axis.x {
      width: 1px;
      height: 100%;
      transform-origin: 0 0;
    }
    .axis.y {
      bottom: 0;
      width: 100%;
      height: 1px;
      transform-origin: 100% 0;
    }
    .ball {
      position: absolute;
      z-index: 2;
      top: 0;
      left: 100%;
      width: 10px;
      height: 10px;
      margin: -5px 0 0 10px;
      background: #FF1461;
      border-radius: 50%;
    }
    svg {
      overflow: visible;
      position: relative;
      z-index: 1;
      width: 100%;
      height: 100%;
    }
    path {
      fill: none;
      stroke: #18FF92;
    }
    button {
      opacity: 1;
      position: relative;
      color: currentColor;
      font-size: 16px;
      width: calc(25% + 1px);
      border: 1px solid #09090B;
      background: transparent;
      margin: -1px 0 0 -1px;
      letter-spacing: 1px;
    }
    label {
      display: flex;
      align-items: center;
      justify-content: center;
      width: calc(100% + 1px);
      margin: -1px 0 0 -1px;
      border-top: 0px;
      border-left: 1px solid #09090B;
      border-right: 1px solid #09090B;
      color: rgba(255,255,255,.3);
    }
    button.active {
      color: #18FF92;
      z-index: 1;
      opacity: 1;
      border: 1px solid currentColor;
      background: #222027;
    }
    button:focus {
      outline: none;
    }
    button:hover {
      background: #222027;
    }
  </style>
</head>
<body>
  <div class="easings">
    <div class="output">
      <div class="visualizer-wrapper grid">
        <div class="axis x"></div>
        <div class="axis y"></div>
        <div class="visualizer">
          <div class="ball" style="transform: translateY(100px) scale(0)"></div>
          <svg viewBox="0 0 100 100">
            <path class="curve"/>
          </svg>
        </div>
      </div>
      <div class="value grid"></div>
    </div>
    <div class="options">
      <label>Ease In</label>
      <button class="active" value="0.550, 0.085, 0.680, 0.530" name="easeInQuad" >Quad</button>
      <button value="0.550, 0.055, 0.675, 0.190" name="easeInCubic" >Cubic</button>
      <button value="0.895, 0.030, 0.685, 0.220" name="easeInQuart" >Quart</button>
      <button value="0.755, 0.050, 0.855, 0.060" name="easeInQuint" >Quint</button>
      <button value="0.470, 0.000, 0.745, 0.715" name="easeInSine" >Sine</button>
      <button value="0.950, 0.050, 0.795, 0.035" name="easeInExpo" >Expo</button>
      <button value="0.600, 0.040, 0.980, 0.335" name="easeInCirc" >Circ</button>
      <button value="0.600, -0.280, 0.735, 0.045" name="easeInBack" >Back</button>
      <label>Ease Out</label>
      <button value="0.250, 0.460, 0.450, 0.940" name="easeOutQuad" >Quad</button>
      <button value="0.215, 0.610, 0.355, 1.000" name="easeOutCubic" >Cubic</button>
      <button value="0.165, 0.840, 0.440, 1.000" name="easeOutQuart" >Quart</button>
      <button value="0.230, 1.000, 0.320, 1.000" name="easeOutQuint" >Quint</button>
      <button value="0.390, 0.575, 0.565, 1.000" name="easeOutSine" >Sine</button>
      <button value="0.190, 1.000, 0.220, 1.000" name="easeOutExpo" >Expo</button>
      <button value="0.075, 0.820, 0.165, 1.000" name="easeOutCirc" >Circ</button>
      <button value="0.175, 0.885, 0.320, 1.275" name="easeOutBack" >Back</button>
      <label>Ease In Out</label>
      <button value="0.455, 0.030, 0.515, 0.955" name="easeInOutQuad" >Quad</button>
      <button value="0.645, 0.045, 0.355, 1.000" name="easeInOutCubic" >Cubic</button>
      <button value="0.770, 0.000, 0.175, 1.000" name="easeInOutQuart" >Quart</button>
      <button value="0.860, 0.000, 0.070, 1.000" name="easeInOutQuint" >Quint</button>
      <button value="0.445, 0.050, 0.550, 0.950" name="easeInOutSine" >Sine</button>
      <button value="1.000, 0.000, 0.000, 1.000" name="easeInOutExpo" >Expo</button>
      <button value="0.785, 0.135, 0.150, 0.860" name="easeInOutCirc" >Circ</button>
      <button value="0.680, -0.550, 0.265, 1.550" name="easeInOutBack" >Back</button>
    </div>
  </div>
  <script>

  var pathEl = document.querySelector('.curve');
  var presetsEls = document.querySelectorAll('.options button');
  var ratio = window.innerWidth >= 980 ? 2 : 1;

  var timeline = anime.timeline({
    loop: true
  });

  function animateProgress(easingName) {

    timeline.pause();

    timeline = anime.timeline({
      loop: true
    });

    timeline.add([
      {
        targets: '.axis.x',
        opacity: [
          { value: [0, 1], delay: 0, duration: 500 },
          { value: 0, delay: 1500, duration: 500 }
        ],
        translateX: { value: [0, (200 * ratio)], delay: 500, duration: 1500 },
        easing: 'linear',
        offset: 0
      }, {
        targets: '.axis.y',
        opacity: [
          { value: [0, 1], delay: 0, duration: 500 },
          { value: 0, delay: 1500, duration: 500 }
        ],
        translateY: { value: [0, -(200 * ratio)], delay: 500, duration: 1500, easing: easingName },
        easing: 'linear',
        offset: 0
      }, {
        targets: '.ball',
        translateY: { value: [100, 0], delay: 500, duration: 1500, easing: easingName },
        scale: [
          { value: [0, 1], delay: 0, duration: 500, easing: 'easeOutBack' },
          { value: 0, delay: 1500, duration: 500, easing: 'easeInBack' }
        ],
        offset: 0
      }
    ]);

  }

  function convertCoordinates(coords) {
    var x1 = coords[0] * 100;
    var y1 = 100 - (coords[1] * 100);
    var x2 = coords[2] * 100;
    var y2 = 100 - (coords[3] * 100);
    return 'M0 100C' + x1 + ' ' + y1 + ' ' + x2 + ' ' + y2 + ' 100 0';
  }

  function getCoordinates(value) {
    return convertCoordinates(value.split(','));
  }

  function changeEase(event) {
    for (var i = 0; i < presetsEls.length; i++) {
      presetsEls[i].classList.remove('active');
    }
    var buttonEl = event.target;
    var value = buttonEl.value;
    var name = buttonEl.name;
    buttonEl.classList.add('active');
    var coordinates = getCoordinates(value);
    animateProgress(name);
    anime.remove(pathEl);
    anime({
      targets: pathEl,
      d: coordinates
    });
  }

  for (var i = 0; i < presetsEls.length; i++) {
    presetsEls[i].onclick = changeEase;
  }

  presetsEls[0].click();

  pathEl.setAttribute('d', getCoordinates(presetsEls[0].value));

  </script>
</body>
</html>
